﻿import { h, defineComponent, resolveComponent, markRaw, toRaw, inject, nextTick, computed } from 'vue'

import {
    ElFormItem, ElInput, ElInputNumber, ElSelect, ElOption, ElCheckbox, ElTreeSelect,
    ElDatePicker, ElTimePicker, ElTimeSelect, ElRadioGroup, ElRadio, ElCheckboxGroup, ElOptionGroup, ElRadioButton, ElSwitch
} from 'element-plus'
import ImageUploader from './ImageUploader.vue'
import FileUploader from './FileUploader.vue'
import MyContent3 from './MyContent3.vue'
import MyChildGrid from './MyChildGrid.vue'
import MyGrid from './MyGrid.vue'
import MySelectInput from './MySelectInput.vue'
import MyAddressInput from './MyAddressInput.vue'
import MySelect from './MySelect.vue'
import HandWriteBoard from './other/HandWriteBoard.vue'

import mydate from './mydate.js'
import _Utils from './Utils.js'
import IphoneDate from './other/IphoneDate.vue'
import MyDateTime3 from './MyDateTime3.vue'
import { useFormItem } from 'element-plus'
import MyVideoRecord from './other/MyVideoRecord.vue'
import MyCheckBox from './MyCheckBox.vue'
import SelectEditText from './sztbhz/SelectEditText.js'
import AudioText from './other/AudioText.vue'
import MyTreeSelectInput from './MyTreeSelectInput.vue'

const myFormItem = defineComponent({
    name: "MyFormItem",
    emits: ["update:modelValue", "update:nameValue"],
    props: {
        field: {
            type: Object,
            required: true
        },
        tb:Object,
        computeData: Object,
        formData: Object,
        modelValue: [String, Number, Date, Boolean, Array, Object],
    },
    created() {
        this.value = this.modelValue
        // if (this.field.control == "select") {
        //     this.loadSelectData();
        // }
    },
    setup(props, { expose }) {
        //这样才能取到所在form
        const { form } = useFormItem();
        const disabled2 = computed(() => {
            //返回所在form的状态
            return form && form.disabled;
        });
        return {
            elForm2: form,
            disabled2: disabled2
        }
    },
    data() {
        return {
            options: [],
            mypage: null,
        }
    },
    watch: {
        //动态更新field属性的时候，更新组件，例如：动态生成options,或者动态修改label
        field: {
            handler() {
                this.$forceUpdate();
            },
            deep: true
        }
    },
    render() {
        //组件所在的宿主页
        this.mypage = inject("MyPage");
        if (!this.$options.components) {
            //把页面上局部注册的组件注册进来，否则无法解析（vue不支持多层解析）
            if (this.mypage && this.mypage.$options.components) {
                this.$options.components = this.mypage.$options.components;
            }
        }

        if (this.field.type == "hidden" || this.field.control == "hidden") return;

        if (this.field.vif == false) return;

        if (this.field.vif) {
            if (typeof (this.field.vif) == "string") {
                let vifvalue = this.computeData[this.field.vif];
                if (vifvalue == false) return;
            }
        }

        var cfg = {
            ...this.$attrs,
            label: this.field.form_label || this.field.label,
            prop: this.field.code,
        };

        // if(this.field.type=="bool" && this.field.control=="check"){
        //     delete cfg.label;
        // }

        if (this.field.label == "" && this.field.type == "array") {
            cfg.labelWidth = "0";
        }

        if (this.field.hideTitle) {
            return this.getControl();
        }
        let children = {
            default: () => this.getControl()
        };
        if (!this.getDisabled() && this.field.control == "check" && this.field.options && (!this.field.check || this.field.check.selectAll != false)) {
            //checkbox多选框， label slot, 用checkbox替换， 全部选中/取消
            children.label = () => h(ElCheckbox, {
                onClick: (e) => {
                    let checked = !e.currentTarget.classList.contains("is-checked");
                    let vals = checked ? this.field.options.map(p => p.value) : [];
                    if (this.field.type == "string") {
                        vals = vals.join(this.field?.check?.splitTag || ";");
                    }
                    nextTick(() => {
                        this.$emit('update:modelValue', vals);
                    });
                }
            }, { default: () => this.field.form_label || this.field.label })
        }
        return h(ElFormItem, cfg, children);
    },

    methods: {
        getCtrAttr(_attr) {
            if (!_attr) return _attr;
            if(typeof(_attr)!="object") return _attr;
            let attr = {};
            //自定义组件中，如说属性用@开头，则传入formData中同名属性，
            //如果单独一个@，则传入整个fromData
            //例如：有的组件需要用到formData中多个字段， 单纯一个modelValue不够用
            Object.keys(_attr).forEach(key => {
                let val = _attr[key];
                if (val && typeof (val) == "object") {
                    if (Array.isArray(val)) {
                        val = val.map(p => this.getCtrAttr(p));
                    } else {
                        val = this.getCtrAttr(val);
                    }
                }
                if (key.startsWith("@")) {
                    key = key.substring(1);
                    if (typeof val == "string") {
                        if (val == "@") {
                            val = this.formData;
                        } else if (val.startsWith("_")) {
                            val = this.computeData[val];
                        } else {
                            val = this.formData[val];
                        }

                    }
                }
                if (typeof val == "string") {
                    if (val == "@") {
                        val = this.formData;
                    } else if (val.startsWith("@")) {
                        val = val.substring(1);
                        if (val.startsWith("_")) {
                            val = this.computeData[val];
                        } else {
                            val = this.formData[val];
                        }
                    }
                }

                if (this.mypage && key.startsWith("on") && typeof (val) == "function") {
                    //自定义控件上的事件，this绑定到所属页，这些事件里面this即可获得所属form页
                    val = val.bind(this.mypage);
                }
                attr[key] = val;
            });

            return toRaw(attr);
        },
        getDisabled() {
            if (this.disabled2) return true;

            if (typeof (this.field.editable) == "string") {
                return !this.computeData[this.field.editable];
            }
            if (typeof (this.field.editable) == "function") {
                let val1 = this.field.editable.apply(this);
                return !val1;
            }
            return !this.field.editable;
        },
        getControl() {
            try {
                if (this.field.tpl && this.field.control == this.field.tpl.control) {
                    return this.getTplControl();
                }
                switch (this.field.control) {
                    case "video":
                        return this.getVideoCtr();
                    case "sign":
                        return this.getSignCtr();
                    case "check":
                        return this.getCheckCtr();
                    case "radio":
                        return this.getRadioCtr();
                    case "text":
                        return this.getTextCtr();
                    case "textarea":
                        return this.getTextAreaCtr();
                    case "number":
                        return this.getNumberCtr();
                    case "date":
                        return this.getDateCtr();
                    case "time":
                        return this.getTimeCtr();
                    case "datetime":
                        return this.getDateTimeCtr();
                    case "combo":
                        return this.getComboCtr();
                    case "photo":
                        return this.getPhotoCtr();
                    case "file":
                        return this.getFileCtr();
                    case "select":
                        return this.getSelectCtr();
                    case "content3":
                        return this.getContent3Ctr();
                    case "cgrid":
                        return this.getChildGridCtr();
                    case "grid":
                        return this.getGridCtr();
                    case "addr":
                        return this.getAddrCtr();
                    case "selectinput":
                        return this.getSelectInputCtr();
                    case "treeselect":
                        return this.getTreeSelectInputCtr();
                }
                return this.getOtherCtr();
            } catch (e) {
                console.log(e);
            }
        },
        getVideoCtr() {
            var attr = {
                ...this.getCtrAttr(this.field.sign),
                ...this.$attrs,
                modelValue: this.modelValue,
                'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                disabled: this.getDisabled()
            }
            if (!attr.style) {
                attr.style = "width:100%";
            }
            return h(MyVideoRecord, attr);
        },

        getSignCtr() {
            var attr = {
                ...this.getCtrAttr(this.field.sign),
                ...this.$attrs,
                modelValue: this.modelValue,
                'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                disabled: this.getDisabled()
            }
            if (!attr.style) {
                attr.style = "width:100%";
            }
            return h(HandWriteBoard, attr);
        },

        getTplControl() {
            const cmp = resolveComponent(this.field.tpl.control);
            if (cmp) {
                var attr = {
                    ...this.getCtrAttr(this.field.tpl.props),
                    modelValue: this.modelValue,
                    'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                }
                if (cmp.props["formData"]) {
                    attr.formData = this.formData;
                }
                if (cmp.props["disabled"]) {
                    attr.disabled = this.getDisabled();
                }

                if (!attr.style) {
                    attr.style = "width:100%";
                }

                //添加自定义组件对slots的支持，把slots作为组件定义导入
                if (this.field.slots) {
                    if (!this.field._lucas_slots) {
                        //为了提高效率编译结果缓存到_lucas_slots变量中
                        let slots = {};
                        Object.keys(this.field.slots).forEach(p => {
                            let cmpDefine = toRaw(this.field.slots[p]);
                            //名字就是slot的名字，内容作为异步组件定义内容
                            const cmp1 = defineComponent(cmpDefine);
                            slots[p] = (props) => h(cmp1, props);
                        })
                        this.field._lucas_slots = markRaw(slots);
                    }
                }
                return h(cmp, attr, this.field._lucas_slots);
            }
            return [];
        },
        getOtherCtr() {
            let ctrl = this.field[this.field.control];
            
            let ctlSlots = [];
            if(ctrl && !this.field._lucas_slots){
                Object.keys(ctrl).filter(x=>x.startsWith("#")).forEach(x=>{
                    ctlSlots.push({key:x.substring(1), slot:ctrl[x]});
                    delete ctrl[x];
                });
            }
            

            const cmp = resolveComponent(this.field.control);

            if (cmp && cmp != this.field.control) {
                var attr = this.getCtrAttr({
                    ...this.$attrs,
                    ...toRaw(ctrl),
                    ...toRaw(this.field[this.field.ext]),
                });

                if (this.field.options) {
                    attr.options = this.field.options;
                }


                //扩展组件 props
                let props = { ...cmp.props };
                if (cmp.extends && cmp.extends.props) {
                    props = { ...cmp.extends.props, ...props };
                }

                if ("options" in props && this.field.options && !attr.options) {
                    attr.options = this.field.options;
                }
                if ("formData" in props) {
                    attr.formData = this.formData;
                }
                if ("computeData" in props) {
                    attr.computeData = this.computeData;
                }
                if ("tb" in props) {
                    attr.tb = this.tb;
                }
                if ("disabled" in props) {
                    attr.disabled = this.getDisabled();
                }

                if ("modelValue" in props) {
                    attr.modelValue = this.modelValue;
                    //自定义属性，有可能覆盖默认的modelValue值，比如同一个field，两个control，各显示一部分内容
                    attr['onUpdate:modelValue'] = value => this.$emit('update:modelValue', value);
                }


                if (!attr.style) {
                    attr.style = "width:100%";
                }

                //添加自定义组件对slots的支持，把slots作为组件定义导入
                if (ctlSlots && ctlSlots.length>0 && !this.field._lucas_slots) {
                    //为了提高效率编译结果缓存到_lucas_slots变量中
                    let slots = {};
                    ctlSlots.forEach(p => {
                        let cmpDefine = toRaw(p.slot);
                        //名字就是slot的名字，内容作为异步组件定义内容
                        const cmp1 =  typeof(cmpDefine)=="string"? resolveComponent(cmpDefine) : defineComponent(cmpDefine);
                        slots[p.key] = (props) => h(cmp1, props);
                    })
                    this.field._lucas_slots = markRaw(slots);
                }
                return h(cmp, attr, this.field._lucas_slots);
            } else {
                console.log("未知的组件名称：" + this.field.control)
            }
            return [];
        },
        getAddrCtr() {
            var attr = {
                ...this.getCtrAttr(this.field.addr),
                ...this.$attrs,
                modelValue: this.modelValue,
                'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                disabled: this.getDisabled()
            }
            if (!attr.style) {
                attr.style = "width:100%";
            }
            return h(MyAddressInput, attr);
        },
        getSelectInputCtr() {
            try {
                var attr = {
                    ...this.getCtrAttr(this.field.selectinput),
                    ...this.$attrs,
                    modelValue: this.modelValue,
                    formData: this.formData,
                    'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                    'onUpdate:nameValue': value => {
                        this.$emit("update:nameValue", value);
                    },
                    'onSelected': value => this.$emit("selected", value),
                    disabled: this.getDisabled()
                };
                delete attr["label"];
                if(!this.field.required){
                    attr["clearable"] = true;
                }

                return h(MySelectInput, attr);
            } catch (e) {
                console.log("SelectInputCtr错误：" + e);
            }
        },
        getTreeSelectInputCtr() {
            try {
                var attr = {
                    ...this.getCtrAttr(this.field.treeselect),
                    ...this.$attrs,
                    modelValue: this.modelValue,
                    formData: this.formData,
                    'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                    'onUpdate:nameValue': value => {
                        this.$emit("update:nameValue", value);
                    },
                    'onSelected': value => this.$emit("selected", value),
                    disabled: this.getDisabled()
                };
                delete attr["label"];
                return h(MyTreeSelectInput, attr);
            } catch (e) {
                console.log("SelectInputCtr错误：" + e);
            }
        },
        getGridCtr() {
            var attr = {
                ...this.getCtrAttr(this.field.grid),
                ...this.$attrs,
                modelValue: this.modelValue,
                'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                disabled: this.getDisabled()
            }
            return h(MyGrid, attr);
        },
        getChildGridCtr() {
            var attr = {
                ...this.getCtrAttr(this.field.cgrid),
                ...this.$attrs,
                formData: this.formData,
                modelValue: this.modelValue,
                'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                disabled: this.getDisabled()
            }
            return h(MyChildGrid, attr);
        },
        getCheckCtr() {

            let val = this.modelValue;
            if (this.field.check && this.field.check.getValues && typeof (this.field.check.getValues) == "function") {
                val = this.field.check.getValues(val);
            }
            if (this.field.options && this.field.type == "string") {
                if (typeof (this.modelValue) == "string") {
                    //过滤掉重复的选项
                    val = Array.from(new Set(val.split(this.field?.check?.splitTag || ";").filter(p => p.length > 0)));
                }
                val = val || [];
            }
            val = val;
            var attr = {
                ...this.getCtrAttr(this.field.check),
                ...this.$attrs,
                modelValue: val,
                'onUpdate:modelValue': value => {
                    if (this.field.check && this.field.check.setValues && typeof (this.field.check.setValues) == "function") {
                        value = this.field.check.setValues.apply(this, value);
                    } else if (this.field.options && (this.field.type == "string" || this.field.type == "int" || typeof (this.modelValue) == "string")) {
                        value = (value || []).join(this.field?.check?.splitTag || ";");
                    }
                    this.$emit('update:modelValue', value)
                },
                disabled: this.getDisabled(),
            }


            if (this.field.options) {
                return h(ElCheckboxGroup, attr, ()=>this.getCheckOptions(val));
            } else {
                if (this.field.check && this.field.check.activeText) {
                    return h(ElSwitch, attr);
                }
                return h(MyCheckBox, attr);
            }
        },
        getCheckOptions(val) {
            var allops = this.field.options.map(x=>x);
            var options = [];

            const isStr = allops.length>0 && isNaN( parseInt(allops[0].value))

            //以前的选项被修改了，但是需要显示出来，状态变为disabled
            if(isStr && val && Array.isArray(val)){
                const oldIts = val.filter(it=>this.field.options.find(x=>x.value==it)==null);
                if(oldIts.length>0){
                    //有以前选中过，但是现在不在选项清单中
                    oldIts.forEach(it=>{
                        allops.push(({label:it, value: it, old:true}))
                    })

                    allops.sort((a,b)=>a.value.localeCompare(b.value))
                }
            }


            allops.forEach(op=>{
                let attr = { label: op.value, value: op.value }
                if(op.old){
                    //以前选中过，但是现在不在选项清单中，还是可以显示出来，但是不能再被选中，并且用删除线标示
                    attr.disabled = true;
                    attr.style={"text-decoration":"line-through"};
                }
                options.push(h(ElCheckbox, attr, { default: () => op.label }));
            })
            return options;
        },
        getRadioCtr() {
            var attr = {
                ...this.getCtrAttr(this.field.radio),
                ...this.$attrs,
                modelValue: this.modelValue,
                'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                disabled: this.getDisabled()
            }
            return h(ElRadioGroup, attr, this.getRadioOptions);
        },
        getRadioOptions() {
            var options = [];
            if(!this.field.options) return null;
            
            let radioElement = ElRadio;
            if (this.field.radio && this.field.radio.type == "button") {
                radioElement = ElRadioButton;
            }
            for (var ix = 0; ix < this.field.options.length; ix++) {
                let op = this.field.options[ix];
                options.push(h(radioElement, { label: op.value }, { default: () => op.label }));
            }
            return options;
        },
        getTextCtr() {
            var attr = {
                ...this.getCtrAttr(this.field.text),
                ...this.$attrs,
                modelValue: this.modelValue,
                'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                disabled: this.getDisabled()
            }
            if (!attr.style) {
                attr.style = "width:100%";
            }
            if(attr.typeOf && typeof(attr.typeOf)=="string"){
                attr.type="text";
                return h(SelectEditText, attr);
            }
            return h(ElInput, attr);
        },
        getTextAreaCtr() {
            var attr = {
                ...this.getCtrAttr(this.field.textarea),
                ...this.$attrs,
                modelValue: this.modelValue,
                'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                disabled: this.getDisabled(),
                type:"textarea"
            };
            if (!attr.style) {
                attr.style = "width:100%";
            }
            if(attr.typeOf && typeof(attr.typeOf)=="string"){
                return h(SelectEditText, attr);
            }
            if(attr.audio2Text){
                return h(AudioText, attr);
            }
            return h(ElInput, attr);
        },

        getNumberCtr() {
            var attr = {
                ...this.getCtrAttr(this.field.number),
                ...this.$attrs,
                modelValue: this.modelValue ? parseFloat(this.modelValue) : 0,
                'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                disabled: this.getDisabled()
            }
            if (!attr.style) {
                attr.style = "width:100%";
            }
            return h(ElInputNumber, attr);
        },
        getDateCtr() {
            let dt = mydate.parseDate(this.modelValue);
            dt = dt ? mydate.formatDate(dt, "yyyy-MM-dd") : "";
            var attr = {
                ...this.getCtrAttr(this.field.date),
                ...this.$attrs,
                modelValue: dt,
                'onUpdate:modelValue': value => this.$emit('update:modelValue', mydate.parseDate(value)),
                disabled: this.getDisabled()
            }
            if (!attr.style) {
                attr.style = "width:100%";
            }
            if (this.field.format) {
                attr.modelValue = mydate.formatDate(this.modelValue, this.field.format);
            }
            // if (this.$mbh5 && !this.field.date) {
            //     attr.type = "date";
            //     if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
            //         //iphone使用原生input组件输入日期， ElInput有问题
            //         return h(IphoneDate, attr);
            //     }
            //     return h(ElInput, attr);
            // }
            attr.editable = false;
            return h(ElDatePicker, attr);
        },
        getTimeCtr() {
            let dt = this.modelValue;
            if (this.field.type == "date" && dt) {
                dt = mydate.parseDate(this.modelValue);
                dt = dt ? mydate.formatDate(dt, "HH:mm") : "";
            } else if (typeof (dt) == "string" && dt.length > 10) {
                dt = mydate.parseDate(this.modelValue);
                dt = dt ? mydate.formatDate(dt, "HH:mm") : "";
            }
            var attr = {
                ...this.field.date,
                ...this.$attrs,
                modelValue: dt,
                'onUpdate:modelValue': value => {
                    if (value && typeof (value) == "string" && value.length <= 8) {
                        value = mydate.parseDate("2001-01-01 " + value);
                    } else {
                        value = mydate.parseDate(value);
                    }
                    if (this.field.type == "string") {
                        this.$emit('update:modelValue', mydate.formatDate(value, "HH:II"));
                    } else {
                        this.$emit('update:modelValue', value);
                    }
                },
                disabled: this.getDisabled()
            }
            if (!attr.style) {
                attr.style = "width:100%";
            }
            attr.start = "00:00";
            attr.end = "23:50";
            attr.step = "00:05";
            attr.editable = false;
            attr.clearable = true;
            return h(ElTimeSelect, attr);
        },
        getDateTimeCtr() {
            let dt = mydate.parseDate(this.modelValue);
            dt = dt ? mydate.formatDate(dt, "yyyy-MM-dd HH:mm:ss") : "";
            var attr = {
                ...this.field.date,
                ...this.$attrs,
                type: "datetime",
                modelValue: dt,
                'onUpdate:modelValue': value => this.$emit('update:modelValue', mydate.parseDate(value)),
                disabled: this.getDisabled()
            }
            if (!attr.style) {
                attr.style = "width:100%";
            }
            if (this.field.format) {
                attr.modelValue = mydate.formatDate(this.modelValue, this.field.format);
            }
            // if (this.$mbh5) {
            //     attr.type = "datetime";
            //     if (navigator.userAgent.indexOf("iPhone") != -1) {
            //         return h(IphoneDate, attr);
            //     } else {
            //         return h(MyDateTime3, attr);
            //     }
            // }
            return h(ElDatePicker, attr);
        },
        getPhotoCtr() {
            var attr = {
                ...this.getCtrAttr(this.field.photo),
                ...this.$attrs,
                formData: this.formData,
                modelValue: this.modelValue,
                'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                disabled: this.getDisabled()
            }
            return h(ImageUploader, attr);
        },
        getFileCtr() {
            var attr = {
                ...this.getCtrAttr(this.field.file),
                ...this.$attrs,
                formData: this.formData,
                modelValue: this.modelValue,
                'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                disabled: this.getDisabled()
            }
            return h(FileUploader, attr);
        },
        getComboCtr() {
            //特殊处理 select多选，值用分号分隔的情况
            let val = this.modelValue;
            if(val){
                let isMulti = this.field.combo?.multiple;
                let splitChar = this.field.combo?.splitChar || ";";
                let opitemIsInt = this.field.options && this.field.options.length>0 && typeof(this.field.options[0].value)=="number";
                if(isMulti){
                    val = val.split(splitChar);
                    if(opitemIsInt){
                        val = val.map(x=> parseInt(x));
                    }
                }else if(opitemIsInt){
                    val = parseInt(val);
                }
            }
            //动态从服务器上查询可选项
            if(this.field.combo?._remoteMethod && !this.field.combo.remoteMethod){
                const me = this;
                this.field.combo.remoteMethod = function(query){
                    if(query){
                        Promise.resolve(me.field.combo._remoteMethod.apply(this, [query])).then(res=>{
                            me.field.options = res;
                        })
                    }
                }
            }
            var comboAttr = this.getCtrAttr(this.field.combo);
            var attr = {
                ...comboAttr,
                ...this.$attrs,
                modelValue: val,
                'onUpdate:modelValue': value => {
                    if (this.field.combo) {
                        let splitChar = this.field.combo?.splitChar || ";";
                        if (this.field.combo.multiple) {
                            value = (value || []).join(splitChar);
                        }
                        //如果有指定lable字段，更新label字段的内容
                        let lbField = this.field.combo.labelField;
                        if (lbField) {
                            let opitem = this.field.options.find(p1 => p1.value == value);
                            this.formData[lbField] = opitem.label;
                        }
                    }

                    this.$emit('update:modelValue', value)
                },
                disabled: this.getDisabled(),
            }
            if (!attr.style) {
                attr.style = "width:100%";
            }

            if(!this.field.required){
                attr["clearable"] = true;
            }

            //树形选择器
            if (this.field.options && this.field.options.length > 0 && this.field.options[0].children) {
                attr.data = this.field.options;
                attr.checkStrictly = true;
                return h(ElTreeSelect, attr);
            }

            return h(ElSelect, attr, this.getOptions);
        },
        getOptions() {
            let ops = this.field.options;
            if (ops.length == 0) return;
            if (ops[0].group) {
                //选项分组的情况
                let groups = {};
                ops.forEach(p => {
                    let key = p.group || "";
                    groups[key] = groups[key] || [];
                    groups[key].push(h(ElOption, p));
                });
                let gps = Object.keys(groups).map(key => {
                    return h(ElOptionGroup, { label: key }, () => groups[key]);
                });
                return gps;
            }
            var options = [];
            options.push(h(ElOption, { label: `--${this.field.label}--`, value: "" }));
            for (var ix = 0; ix < this.field.options.length; ix++) {
                options.push(h(ElOption, this.field.options[ix]));
            }
            return options;
        },
        getSelectCtr() {
            let val = this.modelValue;
            if (this.field.select && this.field.select.multiple && typeof (this.modelValue) == "string") {
                val = val.split(";");
            }
            var attr = {
                ... this.getCtrAttr({ ...this.field.select, ...this.$attrs }),
                modelValue: val,
                formData: this.formData,
                'onUpdate:modelValue': value => {
                    if (this.field.select && this.field.select.multiple && typeof (this.modelValue) == "string") {
                        value = (value || []).join(";");
                    }
                    this.$emit('update:modelValue', value)
                },
                disabled: this.getDisabled(),
                multiple: this.field.select?.multiple
            }
            if (!attr.style) {
                attr.style = "width:100%";
            }
            return h(MySelect, attr, this.getSelectData);
        },


        getSelectData() {
            var items = [];
            (this.options || this.field.options || []).forEach(p => {
                items.push(h(ElOption, p))
            })
            return items;
        },
        // loadSelectData() {
        //     var cfg = this.field.select.cfg || this.field.select;
        //     if (cfg.tbname) {
        //         return this.$server.list(cfg.tbname, 1, 1000, cfg.search).then(res => {
        //             var items = res.records || res;
        //             var lst = [];
        //             for (var ix = 0; ix < items.length; ix++) {
        //                 var newitem = { value: items[ix][cfg.valueField || "ID"], label: items[ix][cfg.labelField || "Name"] };
        //                 lst.push(newitem);
        //             }
        //             this.options = lst;
        //         })
        //     } else {
        //         this.options = this.field.options;
        //     }

        // },
        getContent3Ctr() {
            var attr = {
                ...this.getCtrAttr(this.field.content3),
                ...this.$attrs,
                modelValue: this.modelValue,
                'onUpdate:modelValue': value => this.$emit('update:modelValue', value),
                disabled: this.getDisabled()
            }
            return h(MyContent3, attr);
        }
    }
})

export default myFormItem;